
namespace Tux { namespace Socket
{
    template <typename DomainTraits>
    size_t DatagramSocket<DomainTraits>::Receive(uint8_t* buffer, size_t capacity,
                                                  typename DomainTraits::SocketAddress* source)
    {
        socklen_t socklen = sizeof(typename DomainTraits::SocketAddress);
        ssize_t const bytes = recvfrom(
            BaseSocket::mFD, buffer, capacity, 0, reinterpret_cast<struct sockaddr*>(source),
            &socklen);
        if (bytes >= 0)
            return static_cast<size_t>(bytes);
        if (EAGAIN == errno)
            return 0;
        throw std::runtime_error("receive failed"); // TODO: better exception
    }

    template <typename DomainTraits>
    void DatagramSocket<DomainTraits>::Send(uint8_t* buffer, size_t length,
                                            typename DomainTraits::SocketAddress const& dest)
    {
        ssize_t const sent = sendto(
            BaseSocket::mFD, buffer, length, 0, reinterpret_cast<struct sockaddr const*>(&dest),
            sizeof(typename DomainTraits::SocketAddress));
        if (sent == static_cast<ssize_t>(length))
            return;
        throw std::runtime_error("send failed"); // TODO: better exception
    }
}}

